home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UGeometry.cp < prev    next >
Text File  |  1991-05-01  |  17KB  |  671 lines

  1. #ifndef __STDIO__
  2. #include <StdIO.h>
  3. #endif
  4.  
  5. #ifndef __UGEOMETRY__
  6. #include <UGeometry.h>
  7. #endif
  8.  
  9. #pragma segment Main
  10.  
  11.  
  12. //========================================================================================
  13. // VPoint method definitions
  14. //========================================================================================
  15.  
  16. //----------------------------------------------------------------------------------------
  17. // Conversion operator, for converting VPoint to a textual representation of a
  18. // VPoint. "VPoint(v,h)". Formats VPoint in a static character string and returns
  19. // a pointer to that static character string.
  20. //----------------------------------------------------------------------------------------
  21.  
  22. VPoint::operator char*() const
  23. {
  24.     static char textPoint[40];
  25.     
  26.     sprintf (textPoint, "VPoint(%d, %d)", v, h);
  27.     
  28.     return textPoint;
  29. }
  30.  
  31.  
  32. //----------------------------------------------------------------------------------------
  33. // Conversion operator for converting a VPoint to a Point. Note that a newly
  34. // allocated Point is returned. We are not just viewing a VPoint as a Point.
  35. //----------------------------------------------------------------------------------------
  36.  
  37. VPoint::operator Point() const
  38. {
  39.     Point pt;
  40.     
  41.     pt.v = (short) v;
  42.     pt.h = (short) h;
  43.     
  44.     return pt;
  45. }
  46.  
  47.  
  48. //----------------------------------------------------------------------------------------
  49. // Selector operators for VPoint. Selects one of the two coordinates depending
  50. // on the value of the sel parameter.
  51. //----------------------------------------------------------------------------------------
  52.  
  53. VCoordinate& VPoint::operator[](VHSelect sel)
  54. {
  55.     if (sel == vSel)
  56.         return v;
  57.     else
  58.         return h;
  59. }
  60.  
  61. const VCoordinate& VPoint::operator[](VHSelect sel) const
  62. {
  63.     if (sel == vSel)
  64.         return v;
  65.     else
  66.         return h;
  67. }
  68.  
  69.  
  70. //----------------------------------------------------------------------------------------
  71. // Arithmatic operators for VPoint. Addition and subtraction are all that make
  72. // any sense. Both the Add and AddTo forms are defined.
  73. //----------------------------------------------------------------------------------------
  74.  
  75. VPoint VPoint::operator+(const VPoint& pt) const
  76. {
  77.     VPoint returnPt;
  78.     
  79.     returnPt.v = v + pt.v;
  80.     returnPt.h = h + pt.h;
  81.     return returnPt;
  82. }
  83.  
  84. VPoint VPoint::operator-(const VPoint& pt) const
  85. {
  86.     VPoint returnPt;
  87.     
  88.     returnPt.v = v - pt.v;
  89.     returnPt.h = h - pt.h;
  90.     return returnPt;
  91. }
  92.  
  93. VPoint VPoint::operator-() const
  94. {
  95.     VPoint pt;
  96.     
  97.     pt.v = -v;
  98.     pt.h = -h;
  99.     
  100.     return pt;
  101. }
  102.  
  103. VPoint& VPoint::operator+=(const VPoint& pt)
  104. {
  105.     v += pt.v;
  106.     h += pt.h;
  107.     return *this;
  108. }
  109.  
  110. VPoint& VPoint::operator-=(const VPoint& pt)
  111. {
  112.     v -= pt.v;
  113.     h -= pt.h;
  114.     return *this;
  115. }
  116.  
  117.  
  118. //----------------------------------------------------------------------------------------
  119. // Relational operators for VPoint. These are defined by applying the operator in
  120. // question to both coordinates. The condition must hold for both to hold for the
  121. // VPoints the corresponding VPoints.
  122. //----------------------------------------------------------------------------------------
  123.  
  124. Boolean VPoint::operator!=(const VPoint& pt) const
  125. {
  126.     return v != pt.v || h != pt.h;
  127. }
  128.  
  129. Boolean VPoint::operator==(const VPoint& pt) const
  130. {
  131.     return v == pt.v && h == pt.h;
  132. }
  133.  
  134. Boolean VPoint::operator>(const VPoint& pt) const
  135. {
  136.     return v > pt.v && h > pt.h;
  137. }
  138.  
  139. Boolean VPoint::operator<(const VPoint& pt) const
  140. {
  141.     return v < pt.v && h < pt.h;
  142. }
  143.  
  144. Boolean VPoint::operator>=(const VPoint& pt) const
  145. {
  146.     return v >= pt.v && h >= pt.h;
  147. }
  148.  
  149. Boolean VPoint::operator<=(const VPoint& pt) const
  150. {
  151.     return v <= pt.v && h <= pt.h;
  152. }
  153.  
  154.  
  155. //----------------------------------------------------------------------------------------
  156. // Some useful methods to send to VPoints.
  157. //----------------------------------------------------------------------------------------
  158.  
  159. void VPoint::ConstrainTo(const VRect& rt)
  160. {
  161.     // If this point is not inside 'rt' then move it to the nearest edge.
  162.     
  163.     if (v < rt.top)
  164.         v = rt.top;
  165.     if (v >= rt.bottom)
  166.         v = rt.bottom - 1;
  167.     if (h < rt.left)
  168.         h = rt.left;
  169.     if (h >= rt.right)
  170.         h = rt.right - 1;
  171. }
  172.  
  173.  
  174. //========================================================================================
  175. // VRect method definitions
  176. //========================================================================================
  177.  
  178. //----------------------------------------------------------------------------------------
  179. // Conversion operator, for converting VRect to a textual representation of a VRect.
  180. // "VRect(top,left,bottom,right)". Formats VRect in a static character string and returns
  181. // a pointer to that static character string.
  182. //----------------------------------------------------------------------------------------
  183.  
  184. VRect::operator char*() const
  185. {
  186.     static char textPoint[80];
  187.     
  188.     sprintf (textPoint, "VRect(%d, %d, %d, %d)", top, left, bottom, right);
  189.     
  190.     return textPoint;
  191. }
  192.  
  193.  
  194. //----------------------------------------------------------------------------------------
  195. // Conversion operator for converting a VRect to a Rect. Note that a newly allocated Rect
  196. // is returned. We are not just viewing a VRect as a Rect. Also a constructor for
  197. // constructing a VRect from a Rect.
  198. //----------------------------------------------------------------------------------------
  199.  
  200. VRect::operator Rect() const
  201. {
  202.     Rect pt;
  203.     
  204.     pt.top = (short) top;
  205.     pt.left = (short) left;
  206.     pt.bottom = (short) bottom;
  207.     pt.right = (short) right;
  208.     
  209.     return pt;
  210. }
  211.  
  212. VRect::VRect(const Rect& rt)
  213. {
  214.     top = rt.top;
  215.     left = rt.left;
  216.     bottom = rt.bottom;
  217.     right = rt.right;
  218. }
  219.  
  220.  
  221. //----------------------------------------------------------------------------------------
  222. // Selector operators for VPoint. Selects one of the two coordinates depending on the
  223. // value of the sel parameter.
  224. //----------------------------------------------------------------------------------------
  225.  
  226. VPoint& VRect::operator[](PointSelector sel)
  227. {
  228.     if (sel == topLeft)
  229.         return *((VPoint *) &top);
  230.     else
  231.         return *((VPoint *) &bottom);
  232. }
  233.  
  234. const VPoint& VRect::operator[](PointSelector sel) const
  235. {
  236.     if (sel == topLeft)
  237.         return *((VPoint *) &top);
  238.     else
  239.         return *((VPoint *) &bottom);
  240. }
  241.  
  242.  
  243. //----------------------------------------------------------------------------------------
  244. // Operators for adding and subtracting one VRect from to/ from another. Both the Add and
  245. // AddTo form of operators are defined.
  246. //----------------------------------------------------------------------------------------
  247.  
  248. VRect VRect::operator+(const VRect& rt) const
  249. {
  250.     VRect returnRect;
  251.     
  252.     returnRect.top = top + rt.top;
  253.     returnRect.left = left + rt.left;
  254.     returnRect.bottom = bottom + rt.bottom;
  255.     returnRect.right = right + rt.right;
  256.     
  257.     return returnRect;
  258. }
  259.  
  260. VRect VRect::operator-(const VRect& rt) const
  261. {
  262.     VRect returnRect;
  263.     
  264.     returnRect.top = top - rt.top;
  265.     returnRect.left = left - rt.left;
  266.     returnRect.bottom = bottom - rt.bottom;
  267.     returnRect.right = right - rt.right;
  268.     
  269.     return returnRect;
  270. }
  271.  
  272. VRect& VRect::operator+=(const VRect& rt)
  273. {
  274.     top += rt.top;
  275.     left+= rt.left;
  276.     bottom += rt.bottom;
  277.     right += rt.right;
  278.     
  279.     return *this;
  280. }
  281.  
  282.  
  283. VRect& VRect::operator-=(const VRect& rt)
  284. {
  285.     top -= rt.top;
  286.     left-= rt.left;
  287.     bottom-= rt.bottom;
  288.     right-= rt.right;
  289.     
  290.     return *this;
  291. }
  292.  
  293.  
  294. //----------------------------------------------------------------------------------------
  295. // Operators for adding and subtracting a VPoint to/ from a VRect. A VPoint is added to a
  296. // VRect by adding the VPoint to both the top-left and bottom-right VPoints that define
  297. // the VRect. Both the Add and AddTo operators are defined. Very convenient for
  298. // translating VRects. These take a point and since VPoint has a constructor that takes
  299. // two VCoordinates the VRect windowRect can be translated 100 pixels in the positive y
  300. // direction by the statement:
  301. //
  302. //    windowRect = windowRect + VPoint (0, 100);    or
  303. //     windowRect += VPoint (0, 100);
  304. //----------------------------------------------------------------------------------------
  305.  
  306. VRect VRect::operator+(const VPoint& pt) const
  307. {
  308.     VRect returnRect;
  309.     
  310.     returnRect.top = top + pt.v;
  311.     returnRect.left = left + pt.h;
  312.     returnRect.bottom = bottom + pt.v;
  313.     returnRect.right = right + pt.h;
  314.     
  315.     return returnRect;
  316. }
  317.  
  318. VRect VRect::operator-(const VPoint& pt) const
  319. {
  320.     VRect returnRect;
  321.     
  322.     returnRect.top = top - pt.v;
  323.     returnRect.left = left - pt.h;
  324.     returnRect.bottom = bottom - pt.v;
  325.     returnRect.right = right - pt.h;
  326.     
  327.     return returnRect;
  328. }
  329.  
  330. VRect VRect::operator-() const
  331. {
  332.     VRect rt;
  333.     
  334.     rt.top = -top;
  335.     rt.left = -left;
  336.     rt.bottom = -bottom;
  337.     rt.right = -right;
  338.     
  339.     return rt;
  340. }
  341.  
  342. VRect& VRect::operator+=(const VPoint& pt)
  343. {
  344.     top += pt.v;
  345.     left+= pt.h;
  346.     bottom+= pt.v;
  347.     right+= pt.h;
  348.     
  349.     return *this;
  350. }
  351.  
  352. VRect& VRect::operator-=(const VPoint& pt)
  353. {
  354.     top -= pt.v;
  355.     left -= pt.h;
  356.     bottom -= pt.v;
  357.     right -= pt.h;
  358.     
  359.     return *this;
  360. }
  361.  
  362.  
  363. //----------------------------------------------------------------------------------------
  364. // Inset a VRect using the coordinates in VPoint for the inset delta
  365. //----------------------------------------------------------------------------------------
  366.  
  367. VRect& VRect::Inset(const VPoint& delta)
  368. {
  369.     top += delta.v;
  370.     left += delta.h;
  371.     bottom -= delta.v;
  372.     right -= delta.h;
  373.     
  374.     return *this;
  375. }
  376.  
  377.  
  378. //----------------------------------------------------------------------------------------
  379. // Equality operators, other relational operator could be defined such as <. But their
  380. // meaning is ambiguous and probably better implemented as methods. For example, aRect <
  381. // bRect could return true if aRect was inside of bRect, or could return true if the area
  382. // of aRect was less than the area of bRect.
  383. //----------------------------------------------------------------------------------------
  384.  
  385. Boolean VRect::operator==(const VRect& rt) const
  386. {
  387.     return
  388.         top == rt.top && left == rt.left &&
  389.         bottom == rt.bottom && right == rt.right;
  390. }
  391.  
  392. Boolean VRect::operator!=(const VRect& rt) const
  393. {
  394.     return
  395.         top != rt.top || left != rt.left ||
  396.         bottom != rt.bottom || right != rt.right;
  397. }
  398.  
  399.  
  400. //----------------------------------------------------------------------------------------
  401. // Two simple area operators, the intersection & and the union ||. The definition of union
  402. // here is to return a VRect that exactly encloses its operands.
  403. //----------------------------------------------------------------------------------------
  404.  
  405. VRect VRect::operator &(const VRect& rt) const
  406. {
  407.     VRect returnRect;
  408.     
  409.     returnRect.top = Max(top, rt.top);
  410.     returnRect.left = Max(left, rt.left);
  411.     returnRect.bottom = Min(bottom, rt.bottom);
  412.     returnRect.right = Min(right, rt.right);
  413.     returnRect.Validate();
  414.     
  415.     return returnRect;
  416. }
  417.  
  418. VRect VRect::operator |(const VRect& rt) const
  419. {
  420.     VRect returnRect;
  421.     
  422.     returnRect.top = Min(top, rt.top);
  423.     returnRect.left = Min(left, rt.left);
  424.     returnRect.bottom = Max(bottom, rt.bottom);
  425.     returnRect.right = Max(right, rt.right);
  426.     
  427.     return returnRect;
  428. }
  429.  
  430.  
  431. //----------------------------------------------------------------------------------------
  432. // Returns true if a valid rectangle (left < right and top < bottom). If not a valid
  433. // rectangle then return false and set all coordinates to 0.
  434. //----------------------------------------------------------------------------------------
  435.  
  436. Boolean VRect::Valid() const
  437. {
  438.     return left < right && top < bottom;
  439. }
  440.  
  441.  
  442. //----------------------------------------------------------------------------------------
  443. // Sets all coordinates to 0 if the VRect is not a valid rectangle.
  444. //----------------------------------------------------------------------------------------
  445.  
  446. Boolean VRect::Validate()
  447. {
  448.     if (!this->Valid())
  449.     {
  450.         top = left = bottom = right = 0;
  451.         return false;
  452.     }
  453.     else
  454.         return true;
  455. }
  456.  
  457.  
  458. //----------------------------------------------------------------------------------------
  459. // Empty returns true if the rectangle is empty.
  460. //----------------------------------------------------------------------------------------
  461.  
  462. Boolean VRect::Empty() const
  463. {
  464.     return right - left <= 0 || bottom - top <= 0;
  465. }
  466.  
  467.  
  468. //----------------------------------------------------------------------------------------
  469. // Length returns the length of a VRect in a given dimension.
  470. //----------------------------------------------------------------------------------------
  471.  
  472. VCoordinate VRect::Length(VHSelect sel) const
  473. {
  474.     if (sel == vSel)
  475.         return bottom - top;
  476.     else
  477.         return right - left;
  478. }
  479.  
  480.  
  481. //----------------------------------------------------------------------------------------
  482. // Size returns the size of a VRect as a VPoint.
  483. //----------------------------------------------------------------------------------------
  484.  
  485. VPoint VRect::Size() const
  486. {
  487.     return VPoint(bottom - top, right - left);
  488. }
  489.  
  490.  
  491. //----------------------------------------------------------------------------------------
  492. // The Contains method takes either a VPoint or a VRect and returns true if the operand is
  493. // inside of the VRect the method is applied to.
  494. //----------------------------------------------------------------------------------------
  495.  
  496. Boolean VRect::Contains (const VPoint& pt) const
  497. {
  498.     // Does the point 'pt' lie within the rectangle of 'this'?
  499.     
  500.     return pt.v >= top && pt.v <= bottom && pt.h >= left && pt.h <= right;
  501. }
  502.  
  503. Boolean VRect::Contains (const VRect& rt) const
  504. {
  505.     // Does the rectangle 'rt' lie withing the rectagle of 'this'?
  506.     
  507.     return Contains (rt[topLeft]) && Contains (rt[botRight]);
  508. }
  509.  
  510.  
  511. //----------------------------------------------------------------------------------------
  512. // Max and Min are two private methods for comparing individual coordinates of VRects.
  513. //----------------------------------------------------------------------------------------
  514.  
  515. VCoordinate VRect::Min (const VCoordinate a, const VCoordinate b) const
  516. {
  517.     return a < b ? a : b;
  518. }
  519.  
  520. VCoordinate VRect::Max (const VCoordinate a, const VCoordinate b) const
  521. {
  522.     return a > b ? a : b;
  523. }
  524.  
  525.  
  526. //========================================================================================
  527. // The following global routines maintain Pascal compatibility. They are basically
  528. // wrappers that call back into the methods in VRect and VPoint. Interfaces for these
  529. // routines are only provided in the Pascal headers. C++ programs should use the methods
  530. // in VRect and VPoint to avoid the additional function call overhead.
  531. //========================================================================================
  532.  
  533. //----------------------------------------------------------------------------------------
  534. // The following routines make dealing with VPoint as arguments much easier. e.g. the
  535. // Resize method used to take v,h coordinate pair, now it takes a VPoint. These routines
  536. // allow one to do arithmetic on the arguments to Resize without creating a temporary
  537. // VPoint.
  538. //
  539. // NOTE: No interface to these functions is defined for C++, since there is a bug in the C
  540. // compiler when using Pascal calling conventions to return structs greater than 4 bytes.
  541. //----------------------------------------------------------------------------------------
  542.  
  543. pascal VPoint CreateVPt(const VCoordinate v, const VCoordinate h)
  544. {
  545.     return VPoint(v, h);
  546. }
  547.  
  548. pascal VPoint VPtAddVPt(const VPoint& aPt, const VPoint& bPt)
  549. {
  550.     return aPt + bPt;
  551. }
  552.  
  553. pascal VPoint VPtSubVPt(const VPoint& aPt, const VPoint& bPt)
  554. {
  555.     return aPt - bPt;
  556. }
  557.  
  558.  
  559. //----------------------------------------------------------------------------------------
  560. // Wrappers for for object Pascal for some of the functions that are defined on the C++
  561. // stack based classes Point, VPoint, Rect, VRect.
  562. //----------------------------------------------------------------------------------------
  563.  
  564. pascal void PtToVPt(const Point thePt, VPoint& theVPt)
  565. {
  566.     theVPt.h = thePt.h;
  567.     theVPt.v = thePt.v;
  568. }
  569.  
  570. pascal Point VPtToPt(const VPoint& theVPt)
  571. {
  572.     return theVPt;
  573. }
  574.  
  575. pascal void RectToVRect(const Rect& theRect, VRect& theVRect)
  576. {
  577.     theVRect.top = theRect.top;
  578.     theVRect.left = theRect.left;
  579.     theVRect.bottom = theRect.bottom;
  580.     theVRect.right = theRect.right;
  581. }
  582.  
  583. pascal void VRectToRect(const VRect& theVRect, Rect& theRect)
  584. {
  585.     theRect = theVRect;
  586. }
  587.  
  588. pascal void AddVPt(const VPoint& srcVPt, VPoint& dstVPt)
  589. {
  590.     dstVPt += srcVPt;
  591. }
  592.  
  593. pascal void SubVPt(const VPoint& srcVPt, VPoint& dstVPt)
  594. {
  595.     dstVPt -= srcVPt;
  596. }
  597.  
  598. pascal void SetVPt(VPoint& vPt, VCoordinate h, VCoordinate v)
  599. {
  600.     vPt.h = h;
  601.     vPt.v = v;
  602. }
  603.  
  604. pascal Boolean EqualVPt(const VPoint& aVPt, const VPoint& bVPt)
  605. {
  606.     return aVPt == bVPt;
  607. }
  608.  
  609. pascal void SetVRect(VRect& vRt,
  610.                      VCoordinate left, VCoordinate top,
  611.                      VCoordinate right, VCoordinate bottom)
  612. {
  613.     vRt.left = left;
  614.     vRt.top = top;
  615.     vRt.right = right;
  616.     vRt.bottom = bottom;
  617. }
  618.  
  619. pascal void OffsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
  620. {
  621.     vRt += VPoint(dv, dh);
  622. }
  623.  
  624. pascal void InsetVRect(VRect& vRt, VCoordinate dh, VCoordinate dv)
  625. {
  626.     vRt.Inset(VPoint(dv, dh));
  627. }
  628.  
  629. pascal void Pt2VRect(const VPoint& theTopLeft, const VPoint& theBotRight, VRect& vRt)
  630. {
  631.     vRt[topLeft] = theTopLeft;
  632.     vRt[botRight] = theBotRight;
  633. }
  634.  
  635. pascal Boolean PtInVRect(const VPoint& vPt, const VRect& vRt)
  636. {
  637.     return vRt.Contains(vPt);
  638. }
  639.  
  640. pascal Boolean EmptyVRect(const VRect& vRt)
  641. {
  642.     return vRt.Empty();
  643. }
  644.  
  645. pascal Boolean EqualVRect(const VRect& aVRt, const VRect& bVRt)
  646. {
  647.     return aVRt == bVRt;
  648. }
  649.  
  650. pascal VCoordinate LengthVRect(const VRect& vRt, VHSelect whichDim)
  651. {
  652.     return vRt.Length(whichDim);
  653. }
  654.  
  655. pascal void PinVRect(const VRect& vRt, VPoint& vPt)
  656. {
  657.     vPt.ConstrainTo(vRt);
  658. }
  659.  
  660. pascal Boolean SectVRect(const VRect& src1, const VRect& src2, VRect& dst)
  661. {
  662.     dst = src1 & src2;
  663.     return dst.Valid();
  664. }
  665.  
  666. pascal void UnionVRect(const VRect& src1, const VRect& src2, VRect& dst)
  667. {
  668.     dst = src1 | src2;
  669. }
  670.  
  671.